package com.example.gulimall.search.thread;

import java.util.concurrent.*;

public  class ThreadTest {
    //创建线程池
    private static ExecutorService executor= Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //测试CompletableFuture
        System.out.println("main.....start....");
        /**
         *   runAsync 没有返回值
         */

//       CompletableFuture.runAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 / 2;
//            System.out.println("运行结果：" + i);
//        }, executor);
//
//        System.out.println("main.....end....");
        /**
         *    supplyAsync有返回值
          */

//        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 /0;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor).whenComplete((reslut,excption)->{
//            //方法执行完的同步回调，不会开启一个新的线程 whenCompleteAsync方法执行完的异步回调，会开启一个新的线程
//            //前一个参数是结果，后一个参数是一异常
//            // 虽然能够得到异常信息，但是没法修改返回数据
//            System.out.println("异步任务成功完成了。。。。结果是"+reslut+";异常是"+excption);
//        }).exceptionally(throwable -> {
//            //exceptionally 结果出现异常的回调
//            //感知异常，同时返回默认值jo
//            return 10;
//        });
        /**
         * 方法完成后的处理,相当于whenComplete和exceptionally的集合
         */
//        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 /4;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor).handle((result,excption)->{
//            if (result!=null){
//                return  result*2;
//            }
//            if (excption!=null){
//                return  0;
//            }
//            return 0;
//        });

        /**
         * 线程串行化
         * 1 thenRunAsync 不能获取到上一步的执行结果，并且没有返回值
         *      thenRunAsync(()->{
         *             System.out.println("任务二启动了");
         *         },executor);
         * 2 thenAcceptAsync 能获取到上一步的执行结果，但没有返回值
         *       .thenAcceptAsync ((result)->{
         *             System.out.println("任务二启动了,上一次执行结果："+result);
         *         },executor);
         * 3 thenApply 能获取到上一步的执行结果，而且有返回值
         *      .thenApply((result)->{
         *             System.out.println("任务二启动了:"+result);
         *             return  "hello"+result;
         *         });
         */
//        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor).thenApply((result)->{
//            System.out.println("任务二启动了:"+result);
//            return  "hello"+result;
//        });
        /**
         * 两个都执行
         */

        //  Integer integer = integerCompletableFuture.get();
//        CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1线程开始：" + Thread.currentThread().getId());
//            int i = 10 / 4;
//
//            System.out.println("任务1线程结束：" + Thread.currentThread().getId());
//            return i;
//        }, executor);
//        CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务2线程开始：" + Thread.currentThread().getId());
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("任务2线程结束：" + Thread.currentThread().getId());
//            return "hello";
//        }, executor);
//        1 runAfterBothAsync 上两个任务执行完后执行,不能感应到上两个任务的执行结果,没有返回值
//        future1.runAfterBothAsync(future2,()->{
//            System.out.println("任务三开始");
//        },executor);
//        2 thenAcceptBothAsync 上两个任务执行完后执行,能感应到上两个任务的执行结果,没有返回值
//        future1.thenAcceptBothAsync(future2,(f1,f2)->{
//            System.out.println("任务三开始。。。。任务1的结果："+f1+"任务2的结果："+f2);
//        },executor);
        //3 thenCombineAsync 上两个任务执行完后执行,能感应到上两个任务的执行结果,有返回值
//        CompletableFuture<String> stringCompletableFuture = future1.thenCombineAsync(future2, (f1, f2) -> {
//            return "任务三开始返回。。。。任务1的结果：" + f1 + "任务2的结果：" + f2;
//        }, executor);

        /**
         * 两任务组合，两个任务钟只要有一个完成就执行任务三
         */
        //1 runAfterEitherAsync  两个任务钟只要有一个完成就执行任务三 不能感知结果，没有返回值
//        future1.runAfterEitherAsync(future2,()->{
//            System.out.println("任务3开始");
//        },executor);
//        2 acceptEitherAsync 两个任务钟只要有一个完成就执行任务三 能感知结果,感知到先执行完的那个任务结果
//        如果先执行完的没有返回结果，则返回null，没有返回值
//        future1.acceptEitherAsync(future2,(result)->{
//            System.out.println("任务3开始。。。。之前的结果："+result);
//        },executor);
//        3 applyToEitherAsync 两个任务钟只要有一个完成就执行任务三 能感知结果,感知到先执行完的那个任务结果
//       如果先执行完的没有返回结果，则返回null，有返回值
//        CompletableFuture<String> stringCompletableFuture = future1.applyToEitherAsync(future2, (result) -> {
//            return result.toString() + "->哈哈";
//        }, executor);
        //stringCompletableFuture.get()阻塞任务，只有任务执行完了，他才会执行

        /**
         * 多任务组合
         */
        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息");
            return "hello.jpg";
        }, executor);
        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性信息");
            return "黑色+256";
        }, executor);
        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("查询商品介绍");
            return "华为";
        }, executor);
//        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
//        allOf.get();//等待所有任务执行完
//        System.out.println("main.....end...."+futureImg.get()+"=>"+futureAttr.get()+"=》"+futureDesc.get());
        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
        anyOf.get();//等待所有任务执行完
        System.out.println("main.....end...."+anyOf.get()); //只要有一个任务做完就执行

    }

}
